/**
 * 手动抛出异常错误只需在service的方法里 throw new HttpException('message', HttpStatus.BAD_REQUEST)
 */

import {
  ArgumentsHost,
  Catch,
  ExceptionFilter,
  HttpException,
  HttpStatus,
  Inject,
} from '@nestjs/common';
import { Response, Request } from 'express';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
import { getReqMainInfo } from '../utils/common';

@Catch(HttpException)
export class HttpExceptionFilter<T> implements ExceptionFilter {
  constructor(
    @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
  ) {}

  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp(); // 获取请求上下文
    const response = ctx.getResponse<Response>(); // 获取请求上下文的response对象
    const request = ctx.getRequest<Request>(); // 获取请求对象
    const status = exception.getStatus(); // 获取异常状态码

    let resultMessage = exception.message;

    // 拦截class-validate错误信息
    try {
      const exceptionResponse = exception.getResponse() as any;
      if (Object.prototype.hasOwnProperty.call(exceptionResponse, 'message')) {
        resultMessage = Array.isArray(exceptionResponse.message)
          ? exceptionResponse.message[0]
          : exceptionResponse.message;
      }
    } catch (e) {}

    const errorResponse = {
      code: -1,
      msg: resultMessage,
    };

    // 记录日志
    this.logger.error(resultMessage, {
      status,
      request: getReqMainInfo(request),
      msg: resultMessage,
    });

    // 设置返回的状态码，请求头，错误信息
    response.status(status);
    response.header('Content-Type', 'application/json; charset=utf-8');
    response.send(errorResponse);
  }
}
